package cn.bookcycle.panda.userweb.controller;


import cn.bookcycle.panda.userweb.constant.URLConstant;

import cn.bookcycle.panda.userweb.pojo.doo.AuthsDO;
import cn.bookcycle.panda.userweb.util.AuthUtil;
import com.baomidou.kisso.SSOHelper;
import com.baomidou.kisso.annotation.Action;
import com.baomidou.kisso.annotation.Login;
import com.baomidou.kisso.common.util.HttpUtil;
import com.baomidou.kisso.security.token.SSOToken;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Date;

/**
 * @author Mason
 * @date 2018/3/27
 */
@Controller
public class AuthsController extends BaseController{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final String LOGIN_SUCCESS="登录成功";
    private final String LOGIN_FAILURE="login failure";
    private final String REGISTER_SUCCESS="注册成功";
    private final String UPDATE_SUCCESS="修改成功";
    private final String USER_SERVICE_ERROR="用户服务器错误";
    private final String BAD_PARAM="无效手机号，或密码过于简单";
    private final String BAD_REQUEST="账号、密码不能为空";
    private final String ACCOUNT_EXIST="账号已经存在";
    private final String ACCOUNT_NOT_EXIST="账号不存在";
    private final String ERROR_UNKNOWN="未知错误，请稍后再试";
    private final String PASSWORD_NOT_EQUAL="密码不一致";
    private final String NO_AUTHORITY="没有权限";

    private String ReturnURL;
    private String IndexURL="http://123.207.115.103:8100/index";
    //微信登录回调地址
    private final String backUrl="http://1174970b.ngrok.io/WxAuth/callBack";

    public static final String APPID="wx991b04b8ede5c804";
    public static final String APPSECRET="dc4211ad824809553e97a6106aac995d";
    @RequestMapping("home")
    public String home(){
        return "home";
    }

    @RequestMapping("forgot")
    public String forget(){
        return "forgot";
    }
    /**
     * 退出登录
     * @return
     */
    @RequestMapping("/logout")
    public String logout(){
        SSOHelper.clearLogin(request,response);
        request.getSession().invalidate();
        return redirectTo("home");
    }
    
    /**
     * 跳转登录页面
     * @return
     */
    @Login(action = Action.Skip)
    @RequestMapping(value = "/signIn")
    public String signIn(@Nullable@RequestParam("ReturnURL")String ReturnURL){
        if(ReturnURL!=null) this.ReturnURL=ReturnURL;
        else this.ReturnURL=this.IndexURL;
        return "sign-in1";
    }

    /**
     * 使用微信登录（开放平台）
     * @return
     */
    @RequestMapping(value ="/wxLogin",method=RequestMethod.GET)
    public String wxLogin() {

        String url="https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + AuthUtil.APPID+
                "&redirect_uri=" + backUrl+
                "&response_type=code" +
                "&scope=snsapi_userinfo" +
                "&state=STATE#wechat_redirect";
        return redirectTo(url);
    }

    /**
     * 微信登录的回调函数
     * @return
     * @throws IOException
     */
    @RequestMapping(value ="/WxAuth/callBack",method=RequestMethod.GET)
    public String callBack() throws IOException{
        String code=request.getParameter("code");
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" +AuthUtil.APPID+
                "&secret=" +AuthUtil.APPSECRET+
                "&code=" +code+
                "&grant_type=authorization_code";
        RestTemplate restTemplate=new RestTemplate();
        ResponseEntity responseEntity=restTemplate.exchange(url,HttpMethod.GET,null,String.class);
        JSONObject jsonObject=JSONObject.fromObject(responseEntity.getBody());
        logger.info(jsonObject.toString());
        String openid=jsonObject.getString("openid");
        String token=jsonObject.getString("access_token");

        String infoUrl="https://api.weixin.qq.com/sns/userinfo?" +
                "access_token=" +token+
                "&openid=OPENID" +openid+
                "&lang=zh_CN";
        ResponseEntity responseEntityInfo=restTemplate.exchange(infoUrl,HttpMethod.GET,null,String.class);
        JSONObject infoJson=JSONObject.fromObject(responseEntityInfo.getBody());
        logger.info(infoJson.toString());
        return "home";
    }

    /**
     * 登录
     * @param identifier
     * @param credential
     * @param type
     * @return
     */
    @Login(action = Action.Skip)
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @ResponseBody
    public String login(@RequestParam("identifier")String identifier,
                        @RequestParam("credential")String credential,
                        @RequestParam("type")String type){
        String ReturnURL=HttpUtil.decodeURL(this.ReturnURL);
        logger.info("return url:"+ReturnURL);
        RestTemplate restTemplate=new RestTemplate();
        MultiValueMap multiValueMap=new LinkedMultiValueMap();
        multiValueMap.add("identifier",identifier);
        multiValueMap.add("credential",credential);
        multiValueMap.add("type",type);
        SSOToken ssoToken=SSOToken.create();
        try{
            String uriParam="/"+identifier+"/"+credential+"/"+type;
            Object auths=restTemplate.getForObject(URLConstant.GET_AUTHS+uriParam,Object.class);
            logger.info(auths.toString());
            JSONObject jsonAuths=JSONObject.fromObject(auths);
            String userId=jsonAuths.getString("userId");
            ssoToken.setId(userId);
            ssoToken.setIp(request);
            SSOHelper.setCookie(request,response,ssoToken,true);
            logger.info("IP:"+ssoToken.getIp()+","+identifier+",login success");
            return ReturnURL;
        }catch (HttpClientErrorException e){
            logger.info(e.getStatusText()+e.getMessage());
            if(e.getStatusCode()==HttpStatus.NOT_FOUND){
                logger.info("login failed,wrong password or not exist");
            }
            return this.LOGIN_FAILURE;
        }
    }

    /**
     * 跳转注册页面
     * @return
     */
    @RequestMapping("signUp")
    public String signUp(){
        return "sign-up1";
    }

    /**
     *
     * @param identifier
     * @param password
     * @param passwordConfirm
     * @param type
     * @return
     */
    @RequestMapping(value = "register",method = RequestMethod.POST)
    @ResponseBody
    public String register(@RequestParam("identifier")String identifier,
                           @RequestParam("credential")String password,
                           @RequestParam("credentialConfirm")String passwordConfirm,
                           @RequestParam("type") String type){
        if(!password.equals(passwordConfirm)){
            return this.PASSWORD_NOT_EQUAL;
        }
        RestTemplate restTemplate=new RestTemplate();
        MultiValueMap<String,Object> multiValueMap=new LinkedMultiValueMap<>();
        String authId=new Date().getTime()+identifier;
        multiValueMap.add("id",authId);
        multiValueMap.add("identifier",identifier);
        multiValueMap.add("credential",password);
        multiValueMap.add("type",type);
        try {
            ResponseEntity<Void> responseEntity=restTemplate.postForEntity(URLConstant.SAVE_AUTHS,multiValueMap,Void.class);
            if(responseEntity.getStatusCode()== HttpStatus.CREATED){
                saveNewUser(authId);
                if(true){
                    return this.REGISTER_SUCCESS;
                }else {
                    return this.USER_SERVICE_ERROR;
                }
            }else {
                return this.ERROR_UNKNOWN;
            }
        }catch (HttpClientErrorException e){
            HttpStatus httpStatus=e.getStatusCode();
            if(HttpStatus.NOT_ACCEPTABLE == httpStatus){
                return this.BAD_PARAM;
            }else if(HttpStatus.CONFLICT == httpStatus){
                return this.ACCOUNT_EXIST;
            }else if(HttpStatus.INTERNAL_SERVER_ERROR == httpStatus){
                return this.USER_SERVICE_ERROR;
            }else if(HttpStatus.BAD_REQUEST == httpStatus){
                return this.BAD_REQUEST;
            }else {
                return this.ERROR_UNKNOWN;
            }
        }
    }

    /**
     * 新生成账号实体的同时，新建对应的用户实体
     * @param authsId
     * @return
     */
    private boolean saveNewUser(String authsId){
        try {
            RestTemplate restTemplate=new RestTemplate();
            JSONObject userJson=new JSONObject();
            userJson.element("id",authsId);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity=new HttpEntity(userJson.toString(),headers);
            restTemplate.exchange(URLConstant.SAVE_USER,HttpMethod.POST,entity,String.class);
            return true;
        }catch (HttpClientErrorException e){
            return false;
        }
    }

    /**
     *
     * @return
     */
//    @RequestMapping("/showAccount")
//    public String showAccount(Model model){
//        SSOToken ssoToken=SSOHelper.getSSOToken(request);
//        String accountId=ssoToken.getId();
//        RestTemplate restTemplate=new RestTemplate();
//
//        ResponseEntity<AccountDO> responseAccount=restTemplate.getForEntity(URLConstant.GET_ACCOUNT_BY_ID+"/"+accountId,AccountDO.class);
//        String telephone=responseAccount.getBody().getTelephone();
//        telephone=telephone.substring(0,3)+"****"+telephone.substring(8,11);
//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
//        String registerTime=sdf.format(responseAccount.getBody().getRegisterTime());
//        model.addAttribute("registerTime",registerTime);
//        model.addAttribute("telephone",telephone);
//        return "account";
//    }
}
